package com.xmtlxx.web.controller.center;

import cn.hutool.http.HttpStatus;
import com.alibaba.fastjson.JSONObject;
import com.xmtlxx.common.config.TengboProperties;
import com.xmtlxx.common.core.controller.BaseController;
import com.xmtlxx.common.core.domain.R;
import com.xmtlxx.common.core.domain.dto.RoleDTO;
import com.xmtlxx.common.core.domain.entity.SysDept;
import com.xmtlxx.common.core.domain.model.LoginUser;
import com.xmtlxx.common.core.page.TableDataInfo;
import com.xmtlxx.common.exception.ServiceException;
import com.xmtlxx.common.helper.LoginHelper;
import com.xmtlxx.common.utils.JsonUtils;
import com.xmtlxx.common.utils.StringUtils;
import com.xmtlxx.common.wxap.util.HttpInvokerUtils;
import com.xmtlxx.common.wxap.util.HttpReqUtil;
import com.xmtlxx.system.service.ISysDataScopeService;
import com.xmtlxx.system.service.ISysDeptService;
import com.xmtlxx.web.controller.center.vo.finance.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Validated
@Api(value = "涉案资金", tags = {"涉案资金"})
@RequiredArgsConstructor
@RestController
@RequestMapping("/app/finance")
@Slf4j
public class FinanceController extends BaseController {

    private static TengboProperties tengboProperties;

    @Autowired
    public void setTengboProperties(TengboProperties tengboProperties) {

        this.tengboProperties = tengboProperties;
    }

    private final ISysDataScopeService iSysDataScopeService;

    private final ISysDeptService iSysDeptService;

    @ApiOperation("初始化参数")
    @GetMapping("/applyInit")
    public R<Map<String, Object>> applyInit() {

        Map<String, Object> data = new HashMap<>();
        data.put("officeIds", getUserDateScopes());
        data.put("userName", getLoginUser().getNickName());
        SysDept dept = iSysDeptService.selectDeptById(getDeptId());
        data.put("deptCode", dept.getDeptCode());
        data.put("deptName", dept.getDeptName());
        if (LoginHelper.getLoginUser().getRolePermission().contains("DeptLeader")) {
            data.put("role", 1);
        }
        if (LoginHelper.getLoginUser().getRolePermission().contains("Finance")) {
            data.put("role", 2);
        }
        if (LoginHelper.getLoginUser().getRolePermission().contains("FinanceLeader")) {
            data.put("role", 3);
        }
        if (LoginHelper.getLoginUser().getRolePermission().contains("FinanceDirector")) {
            data.put("role", 4);
        }
        return R.ok(data);
    }

    @ApiOperation("新增缴费申请查询")
    @PostMapping("/applyList")
    public TableDataInfo<FinanceBo> applyList(@RequestBody FinanceReqeust resq) {

        resq.setOfficeId(getUserDateScopes());
        String respJson = apiRequest("/finance-app/applyList", JsonUtils.toJsonString(resq));
        JSONObject resp = JSONObject.parseObject(respJson);
        if (resp.getInteger("code").equals(200)) {
            FinancePage page = JsonUtils.parseObject(resp.getString("data"), FinancePage.class);
            TableDataInfo<FinanceBo> rspData = new TableDataInfo<>();
            rspData.setCode(HttpStatus.HTTP_OK);
            rspData.setMsg("查询成功");
            rspData.setRows(page.getRecords());
            rspData.setTotal(page.getTotal());
            return rspData;
        } else {
            throw new ServiceException(resp.getString("msg"));
        }
    }

    @ApiOperation("获取款项申请列表")
    @PostMapping("/list")
    public TableDataInfo<FinanceVo> list(@RequestBody FinanceReqeust resq) {

        resq.setOfficeId(getUserDateScopes());
        resq.setUserName(getLoginUser().getNickName());
        Map<String, String> params = new HashMap<>();
        params.put("officeIds", resq.getOfficeId().toString());
        params.put("pageNo", resq.getPageNo() + "");
        params.put("pageSize", resq.getPageSize() + "");
        params.put("userName", getLoginUser().getNickName());
        params.put("paymentType", StringUtils.isEmpty(resq.getPaymentType()) ? "" : resq.getPaymentType());
        params.put("queryInfo", StringUtils.isEmpty(resq.getQueryInfo()) ? "" : resq.getQueryInfo());
        params.put("sort", StringUtils.isEmpty(resq.getSort()) ? "" : resq.getSort());
        String respJson = apiGetRequest("/finance-app/getPaymentHandleApplyPage", params);
        JSONObject resp = JSONObject.parseObject(respJson);
        if (resp.getInteger("code").equals(200)) {
            FinancePage page = JsonUtils.parseObject(resp.getString("data"), FinancePage.class);
            TableDataInfo<FinanceVo> rspData = new TableDataInfo<>();
            rspData.setCode(HttpStatus.HTTP_OK);
            rspData.setMsg("查询成功");
            rspData.setRows(page.getRecords());
            rspData.setTotal(page.getTotal());
            return rspData;
        } else {
            throw new ServiceException(resp.getString("msg"));
        }
    }

    @ApiOperation("机构款项账户查询")
    @GetMapping("/officeAccounts")
    public R<List<OfficeAccount>> officeAccounts() {

        String respJson = apiRequest("/finance-app/officeAccounts", JsonUtils.toJsonString(getUserDateScopes()));
        JSONObject resp = JSONObject.parseObject(respJson);
        if (resp.getInteger("code").equals(200)) {
            return R.ok(JsonUtils.parseArray(resp.getString("data"), OfficeAccount.class));
        } else {
            throw new ServiceException(resp.getString("msg"));
        }
    }

    @ApiOperation("缴费申请")
    @PostMapping("/payApply")
    public R<Void> payApply(@RequestBody FinanceForm form) {

        form.setApplicant(LoginHelper.getNickname());
        String respJson = apiRequest("/finance-app/payApply", JsonUtils.toJsonString(form));
        JSONObject resp = JSONObject.parseObject(respJson);
        if (resp.getInteger("code").equals(200)) {
            return toAjax(1);
        }
        return toAjax(0);
    }

    @ApiOperation("退费申请")
    @PostMapping("/refund")
    public R<Void> refund(@RequestBody FinanceRefundForm form) {

        form.setApplicant(LoginHelper.getNickname());
        String respJson = apiRequest("/finance-app/refund", JsonUtils.toJsonString(form));
        JSONObject resp = JSONObject.parseObject(respJson);
        if (resp.getInteger("code").equals(200)) {
            return toAjax(1);
        }
        return toAjax(0);
    }

    @ApiOperation("缴费详情")
    @GetMapping("/{id}")
    public R<FinanceVo> getFinanceVo(@ApiParam("主键")
                                     @NotNull(message = "主键不能为空")
                                     @PathVariable("id") String id) {

        FinanceReqeust resq = new FinanceReqeust();
        resq.setId(id);
        resq.setOfficeId(getUserDateScopes());
        String respJson = apiRequest("/finance-app/payInfo", JsonUtils.toJsonString(resq));
        JSONObject resp = JSONObject.parseObject(respJson);
        if (resp.getInteger("code").equals(200)) {
            return R.ok(JsonUtils.parseObject(resp.getString("data"), FinanceVo.class));
        } else {
            return R.fail(resp.getString("msg"));
        }
    }

    private String apiRequest(String method, String params) {

        try {
            log.info("ApiRequest Start = >Method:{} Prams:{}", method, params);
            String result = HttpInvokerUtils.PostToJson(tengboProperties.getFinanceurl() + "/" + method, params);
            log.info("ApiRequest Over = >{}", result);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("ApiRequest Error = >{}", e.getMessage());
            FinanceResponse resp = new FinanceResponse();
            resp.setCode(201);
            resp.setMsg(e.getMessage());
            return JsonUtils.toJsonString(resp);
        }
    }

    private String apiGetRequest(String method, Map<String, String> params) {

        try {
            String url = HttpReqUtil.setParmas(params, tengboProperties.getFinanceurl() + "/" + method, "");
            log.info("ApiRequest Start = >Method:{} Prams:{}", method, url);
            String result = HttpInvokerUtils.GET(url);
            log.info("ApiRequest Over = >{}", result);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("ApiRequest Error = >{}", e.getMessage());
            FinanceResponse resp = new FinanceResponse();
            resp.setCode(201);
            resp.setMsg(e.getMessage());
            return JsonUtils.toJsonString(resp);
        }
    }

    public List<String> getUserDateScopes() {

        List<String> officeList = new ArrayList<>();
        if (LoginHelper.isAdmin()) {
            return iSysDataScopeService.selectDeptCodesByRoleIds(null, null, null, null);
        }
        if (LoginHelper.isTenantAdmin()) {
            return iSysDataScopeService.selectDeptCodesByRoleIds(null, null, null, LoginHelper.getTenantId());
        }

        LoginUser user = LoginHelper.getLoginUser();
        if (user != null && user.getRoles() != null && user.getRoles().size() > 0) {
            List<String> scopes = user.getRoles().stream().map(RoleDTO::getDataScope).collect(Collectors.toList());
            List<Long> roleIds = user.getRoles().stream().map(RoleDTO::getRoleId).collect(Collectors.toList());

            scopes.forEach(scope -> {
                if ("1".equals(scope)) {//全部
                    officeList.addAll(iSysDataScopeService.selectDeptCodesByRoleIds(null, null, null, null));
                } else if ("2".equals(scope)) {//自定数据权限
                    officeList.addAll(iSysDataScopeService.selectDeptCodesByRoleIds(null, null, roleIds, null));
                } else if ("3".equals(scope)) {//部门数据权限
                    officeList.addAll(iSysDataScopeService.selectDeptCodesByRoleIds(user.getDeptId(), null, null, null));
                } else if ("4".equals(scope)) {//部门及以下数据权限
                    officeList.addAll(iSysDataScopeService.selectDeptCodesByRoleIds( null, user.getDeptId(), null, null));
                } else if ("5".equals(scope)) {//仅本人数据权限
                    officeList.addAll(iSysDataScopeService.selectDeptCodesByRoleIds(user.getDeptId(), null, null, null));
                }
            });

        }
        return officeList;
    }

}
